package com.zjcloud.jwgl.algorithm;

import com.zjcloud.jwgl.domain.AcLessonSchedule;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 基于改进遗传算法的智能排课引擎
 * 
 * @author wxl
 * @date 2024-09-13
 */
@Component
public class GeneticScheduleAlgorithm {
    
    /** 种群大小 */
    private static final int POPULATION_SIZE = 100;
    
    /** 最大迭代次数 */
    private static final int MAX_GENERATIONS = 200;
    
    /** 交叉概率 */
    private static final double CROSSOVER_RATE = 0.8;
    
    /** 变异概率 */
    private static final double MUTATION_RATE = 0.1;
    
    /** 精英保留比例 */
    private static final double ELITE_RATE = 0.1;
    
    /** 当前迭代代数 */
// 删除重复的generation字段声明
    
    /** 全局约束条件 */
    private Map<String, Object> constraints = new HashMap<>();
    
    /**
     * 执行排课算法
     * 
     * @param courses 课程列表
     * @param teachers 教师列表
     * @param classrooms 教室列表
     * @param classes 班级列表
     * @param constraints 约束条件列表
     * @return 排课结果
     */
    public List<AcLessonSchedule> schedule(List<Long> courses, List<Long> teachers, 
                                         List<Long> classrooms, List<Long> classes,
                                         Map<String, Object> constraints) {
        // 初始化种群
        List<List<AcLessonSchedule>> population = initializePopulation(courses, teachers, classrooms, classes, constraints);
        
        // 迭代优化
        for (int generation = 0; generation < MAX_GENERATIONS; generation++) {
            // 计算适应度
            Map<List<AcLessonSchedule>, Double> fitnessMap = evaluateFitness(population, constraints);
            
            // 选择操作
            List<List<AcLessonSchedule>> selected = selection(population, fitnessMap);
            
            // 交叉操作
            List<List<AcLessonSchedule>> crossovered = crossover(selected);
            
            // 变异操作
            List<List<AcLessonSchedule>> mutated = mutation(crossovered, constraints);
            
            // 精英保留
            population = elitism(population, mutated, fitnessMap);
            
            // 检查是否达到终止条件
            if (checkTerminationCondition(fitnessMap)) {
                break;
            }
        }
        
        // 返回最优解
        return getBestSolution(population);
    }
    
    /**
     * 初始化种群
     */
    private List<List<AcLessonSchedule>> initializePopulation(List<Long> courses, List<Long> teachers, 
                                                           List<Long> classrooms, List<Long> classes,
                                                           Map<String, Object> constraints) {
        List<List<AcLessonSchedule>> population = new ArrayList<>();
        
        for (int i = 0; i < POPULATION_SIZE; i++) {
            List<AcLessonSchedule> chromosome = generateRandomChromosome(courses, teachers, classrooms, classes);
            population.add(chromosome);
        }
        
        return population;
    }
    
    /**
     * 生成随机染色体（一个可行的课表方案）
     */
    private List<AcLessonSchedule> generateRandomChromosome(List<Long> courses, List<Long> teachers, 
                                                         List<Long> classrooms, List<Long> classes) {
        List<AcLessonSchedule> chromosome = new ArrayList<>();
        Random random = new Random();
        
        // 为每个课程分配时间、教师、教室和班级
        for (Long courseId : courses) {
            AcLessonSchedule schedule = new AcLessonSchedule();
            schedule.setCourseId(courseId);
            schedule.setTeacherId(teachers.get(random.nextInt(teachers.size())));
            schedule.setClassroomId(classrooms.get(random.nextInt(classrooms.size())));
            schedule.setClassId(classes.get(random.nextInt(classes.size())));
            schedule.setWeekDay(random.nextInt(5) + 1); // 1-5 (周一至周五)
            schedule.setLessonNo(random.nextInt(12) + 1); // 1-12
            schedule.setTeacherPreference(random.nextInt(101)); // 0-100
            schedule.setStatus("0"); // 默认正常
            
            chromosome.add(schedule);
        }
        
        return chromosome;
    }
    
    /**
     * 评估适应度
     */
    private Map<List<AcLessonSchedule>, Double> evaluateFitness(List<List<AcLessonSchedule>> population, 
                                                             Map<String, Object> constraints) {
        Map<List<AcLessonSchedule>, Double> fitnessMap = new HashMap<>();
        
        for (List<AcLessonSchedule> chromosome : population) {
            double fitness = calculateFitness(chromosome, constraints);
            fitnessMap.put(chromosome, fitness);
        }
        
        return fitnessMap;
    }
    
    /**
     * 计算单个染色体的适应度
     */
    private double calculateFitness(List<AcLessonSchedule> chromosome, Map<String, Object> constraints) {
        double fitness = 1000.0; // 初始适应度
        
        // 基础冲突检查
        fitness -= calculateTeacherConflicts(chromosome) * 50; // 教师时间冲突
        fitness -= calculateClassroomConflicts(chromosome) * 50; // 教室时间冲突
        fitness -= calculateClassConflicts(chromosome) * 50; // 班级时间冲突
        
        // 教师偏好
        fitness += calculateTeacherPreference(chromosome);
        
        // 教室容量约束
        if (constraints.containsKey("classroomCapacities")) {
            @SuppressWarnings("unchecked")
            Map<Long, Integer> classroomCapacities = (Map<Long, Integer>) constraints.get("classroomCapacities");
            fitness -= calculateClassroomCapacityViolations(chromosome, classroomCapacities) * 30;
        }
        
        // 连堂课约束
        fitness -= calculateContinuousCoursePenalty(chromosome) * 20;
        
        // 教师工作量约束
        if (constraints.containsKey("teacherWorkload")) {
            @SuppressWarnings("unchecked")
            Map<Long, Integer> teacherWorkload = (Map<Long, Integer>) constraints.get("teacherWorkload");
            fitness -= calculateTeacherWorkloadPenalty(chromosome, teacherWorkload) * 30;
        }
        
        // 课程优先级约束
        if (constraints.containsKey("coursePriorities")) {
            @SuppressWarnings("unchecked")
            Map<Long, Integer> coursePriorities = (Map<Long, Integer>) constraints.get("coursePriorities");
            fitness -= calculateCoursePriorityPenalty(chromosome, coursePriorities) * 25;
        }
        
        // 特殊时间要求约束
        if (constraints.containsKey("specialTimeRequirements")) {
            @SuppressWarnings("unchecked")
            Map<String, List<Integer>> specialTimeRequirements = 
                (Map<String, List<Integer>>) constraints.get("specialTimeRequirements");
            fitness -= calculateSpecialTimeRequirementPenalty(chromosome, specialTimeRequirements) * 40;
        }
        
        // 教室设备要求约束
        if (constraints.containsKey("classroomEquipments")) {
            @SuppressWarnings("unchecked")
            Map<Long, List<String>> classroomEquipments = 
                (Map<Long, List<String>>) constraints.get("classroomEquipments");
            fitness -= calculateClassroomEquipmentPenalty(chromosome, classroomEquipments) * 35;
        }
        
        // 班级课程分布约束
        fitness -= calculateClassDistributionPenalty(chromosome) * 15;
        
        return Math.max(0, fitness); // 确保适应度非负
    }
    
    /**
     * 计算连堂课惩罚值
     */
    private double calculateContinuousCoursePenalty(List<AcLessonSchedule> chromosome) {
        double penalty = 0;
        Map<String, List<AcLessonSchedule>> courseMap = new HashMap<>();
        
        // 按课程ID和星期分组
        for (AcLessonSchedule schedule : chromosome) {
            String key = schedule.getCourseId() + "-" + schedule.getWeekDay();
            courseMap.computeIfAbsent(key, k -> new ArrayList<>()).add(schedule);
        }
        
        // 检查每个课程在同一天的课程安排
        for (List<AcLessonSchedule> schedules : courseMap.values()) {
            if (schedules.size() > 1) {
                schedules.sort((a, b) -> a.getLessonNo().compareTo(b.getLessonNo()));
                for (int i = 0; i < schedules.size() - 1; i++) {
                    // 如果两节课不连续，增加惩罚值
                    if (schedules.get(i + 1).getLessonNo() - schedules.get(i).getLessonNo() != 1) {
                        penalty += 1;
                    }
                }
            }
        }
        
        return penalty;
    }
    
    /**
     * 计算教师工作量惩罚值
     */
    private double calculateTeacherWorkloadPenalty(List<AcLessonSchedule> chromosome, 
                                                Map<Long, Integer> teacherWorkload) {
        double penalty = 0;
        Map<Long, Integer> actualWorkload = new HashMap<>();
        
        // 统计每个教师的实际课时数
        for (AcLessonSchedule schedule : chromosome) {
            actualWorkload.merge(schedule.getTeacherId(), 1, Integer::sum);
        }
        
        // 计算与标准工作量的偏差
        for (Map.Entry<Long, Integer> entry : actualWorkload.entrySet()) {
            Long teacherId = entry.getKey();
            Integer standard = teacherWorkload.getOrDefault(teacherId, 0);
            Integer actual = entry.getValue();
            
            // 实际工作量与标准工作量的差异作为惩罚值
            penalty += Math.abs(actual - standard);
        }
        
        return penalty;
    }
    
    /**
     * 计算课程优先级惩罚值
     */
    private double calculateCoursePriorityPenalty(List<AcLessonSchedule> chromosome, 
                                               Map<Long, Integer> coursePriorities) {
        double penalty = 0;
        
        for (AcLessonSchedule schedule : chromosome) {
            Integer priority = coursePriorities.getOrDefault(schedule.getCourseId(), 0);
            // 优先级高的课程应该安排在上午，下午的课程增加惩罚值
            if (priority > 5 && schedule.getLessonNo() > 4) {
                penalty += (priority - 5);
            }
        }
        
        return penalty;
    }
    
    /**
     * 计算特殊时间要求惩罚值
     */
    private double calculateSpecialTimeRequirementPenalty(List<AcLessonSchedule> chromosome, 
                                                      Map<String, List<Integer>> specialTimeRequirements) {
        double penalty = 0;
        
        for (AcLessonSchedule schedule : chromosome) {
            String key = schedule.getCourseId() + "-" + schedule.getTeacherId();
            List<Integer> allowedTimes = specialTimeRequirements.get(key);
            
            if (allowedTimes != null && !allowedTimes.contains(schedule.getLessonNo())) {
                penalty += 1;
            }
        }
        
        return penalty;
    }
    
    /**
     * 计算教室设备要求惩罚值
     */
    private double calculateClassroomEquipmentPenalty(List<AcLessonSchedule> chromosome, 
                                                   Map<Long, List<String>> classroomEquipments) {
        double penalty = 0;
        
        for (AcLessonSchedule schedule : chromosome) {
            Long courseId = schedule.getCourseId();
            Long classroomId = schedule.getClassroomId();
            
            // 检查课程所需设备是否在教室中
            List<String> requiredEquipments = classroomEquipments.get(courseId);
            List<String> availableEquipments = classroomEquipments.get(classroomId);
            
            if (requiredEquipments != null && availableEquipments != null) {
                for (String equipment : requiredEquipments) {
                    if (!availableEquipments.contains(equipment)) {
                        penalty += 1;
                    }
                }
            }
        }
        
        return penalty;
    }
    
    /**
     * 计算班级课程分布惩罚值
     */
    private double calculateClassDistributionPenalty(List<AcLessonSchedule> chromosome) {
        double penalty = 0;
        Map<Long, Map<Integer, Integer>> classDistribution = new HashMap<>();
        
        // 统计每个班级在每天的课程数量
        for (AcLessonSchedule schedule : chromosome) {
            Long classId = schedule.getClassId();
            Integer weekDay = schedule.getWeekDay();
            
            classDistribution.computeIfAbsent(classId, k -> new HashMap<>())
                            .merge(weekDay, 1, Integer::sum);
        }
        
        // 检查课程分布是否均匀
        for (Map<Integer, Integer> distribution : classDistribution.values()) {
            int minCourses = Integer.MAX_VALUE;
            int maxCourses = 0;
            
            for (int day = 1; day <= 5; day++) {
                int courses = distribution.getOrDefault(day, 0);
                minCourses = Math.min(minCourses, courses);
                maxCourses = Math.max(maxCourses, courses);
            }
            
            // 课程分布差异作为惩罚值
            penalty += (maxCourses - minCourses);
        }
        
        return penalty;
    }
    
    /**
     * 计算教师时间冲突数
     */
    private int calculateTeacherConflicts(List<AcLessonSchedule> chromosome) {
        int conflicts = 0;
        Map<String, List<AcLessonSchedule>> teacherTimeMap = new HashMap<>();
        
        for (AcLessonSchedule schedule : chromosome) {
            String key = schedule.getTeacherId() + "-" + schedule.getWeekDay() + "-" + schedule.getLessonNo();
            teacherTimeMap.computeIfAbsent(key, k -> new ArrayList<>()).add(schedule);
        }
        
        for (List<AcLessonSchedule> schedules : teacherTimeMap.values()) {
            if (schedules.size() > 1) {
                conflicts += schedules.size() - 1;
            }
        }
        
        return conflicts;
    }
    
    /**
     * 计算教室时间冲突数
     */
    private int calculateClassroomConflicts(List<AcLessonSchedule> chromosome) {
        int conflicts = 0;
        Map<String, List<AcLessonSchedule>> classroomTimeMap = new HashMap<>();
        
        for (AcLessonSchedule schedule : chromosome) {
            String key = schedule.getClassroomId() + "-" + schedule.getWeekDay() + "-" + schedule.getLessonNo();
            classroomTimeMap.computeIfAbsent(key, k -> new ArrayList<>()).add(schedule);
        }
        
        for (List<AcLessonSchedule> schedules : classroomTimeMap.values()) {
            if (schedules.size() > 1) {
                conflicts += schedules.size() - 1;
            }
        }
        
        return conflicts;
    }
    
    /**
     * 计算班级时间冲突数
     */
    private int calculateClassConflicts(List<AcLessonSchedule> chromosome) {
        int conflicts = 0;
        Map<String, List<AcLessonSchedule>> classTimeMap = new HashMap<>();
        
        for (AcLessonSchedule schedule : chromosome) {
            String key = schedule.getClassId() + "-" + schedule.getWeekDay() + "-" + schedule.getLessonNo();
            classTimeMap.computeIfAbsent(key, k -> new ArrayList<>()).add(schedule);
        }
        
        for (List<AcLessonSchedule> schedules : classTimeMap.values()) {
            if (schedules.size() > 1) {
                conflicts += schedules.size() - 1;
            }
        }
        
        return conflicts;
    }
    
    /**
     * 计算教师偏好总分
     */
    private double calculateTeacherPreference(List<AcLessonSchedule> chromosome) {
        return chromosome.stream()
                .mapToInt(AcLessonSchedule::getTeacherPreference)
                .sum() / 10.0; // 归一化处理
    }
    
    /**
     * 计算教室容量违反约束的次数
     */
    private int calculateClassroomCapacityViolations(List<AcLessonSchedule> chromosome, 
                                                   Map<Long, Integer> classroomCapacities) {
        int violations = 0;
        Map<Long, Integer> classCapacities = new HashMap<>(); // 假设已知班级人数
        
        for (AcLessonSchedule schedule : chromosome) {
            Long classroomId = schedule.getClassroomId();
            Long classId = schedule.getClassId();
            
            if (classroomCapacities.containsKey(classroomId) && classCapacities.containsKey(classId)) {
                if (classCapacities.get(classId) > classroomCapacities.get(classroomId)) {
                    violations++;
                }
            }
        }
        
        return violations;
    }
    
    /**
     * 选择操作
     */
    private List<List<AcLessonSchedule>> selection(List<List<AcLessonSchedule>> population, 
                                                Map<List<AcLessonSchedule>, Double> fitnessMap) {
        List<List<AcLessonSchedule>> selected = new ArrayList<>();
        int eliteSize = (int) (population.size() * ELITE_RATE);
        
        // 精英选择 - 保留最优个体
        List<List<AcLessonSchedule>> sortedPopulation = population.stream()
            .sorted((a, b) -> Double.compare(fitnessMap.get(b), fitnessMap.get(a)))
            .collect(Collectors.toList());
        
        for (int i = 0; i < eliteSize; i++) {
            selected.add(new ArrayList<>(sortedPopulation.get(i)));
        }
        
        // 锦标赛选择
        int tournamentSize = 5;
        Random random = new Random();
        
        while (selected.size() < population.size()) {
            List<List<AcLessonSchedule>> tournament = new ArrayList<>();
            for (int i = 0; i < tournamentSize; i++) {
                tournament.add(population.get(random.nextInt(population.size())));
            }
            
            List<AcLessonSchedule> winner = tournament.stream()
                .max((a, b) -> Double.compare(fitnessMap.get(a), fitnessMap.get(b)))
                .get();
            
            selected.add(new ArrayList<>(winner));
        }
        
        return selected;
    }
    
    /**
     * 交叉操作
     */
    private List<List<AcLessonSchedule>> crossover(List<List<AcLessonSchedule>> selected) {
        List<List<AcLessonSchedule>> crossovered = new ArrayList<>();
        Random random = new Random();
        
        // 保留精英个体
        int eliteSize = (int) (selected.size() * ELITE_RATE);
        for (int i = 0; i < eliteSize; i++) {
            crossovered.add(new ArrayList<>(selected.get(i)));
        }
        
        // 对剩余个体进行交叉操作
        for (int i = eliteSize; i < selected.size(); i += 2) {
            List<AcLessonSchedule> parent1 = selected.get(i);
            List<AcLessonSchedule> parent2 = i + 1 < selected.size() ? selected.get(i + 1) : selected.get(eliteSize);
            
            if (random.nextDouble() < CROSSOVER_RATE) {
                // 两点交叉
                int point1 = random.nextInt(parent1.size());
                int point2 = random.nextInt(parent1.size());
                int start = Math.min(point1, point2);
                int end = Math.max(point1, point2);
                
                List<AcLessonSchedule> child1 = new ArrayList<>();
                List<AcLessonSchedule> child2 = new ArrayList<>();
                
                for (int j = 0; j < parent1.size(); j++) {
                    if (j >= start && j <= end) {
                        child1.add(cloneSchedule(parent2.get(j)));
                        child2.add(cloneSchedule(parent1.get(j)));
                    } else {
                        child1.add(cloneSchedule(parent1.get(j)));
                        child2.add(cloneSchedule(parent2.get(j)));
                    }
                }
                
                // 修复可能的冲突
                repairSchedule(child1);
                repairSchedule(child2);
                
                crossovered.add(child1);
                crossovered.add(child2);
            } else {
                crossovered.add(new ArrayList<>(parent1));
                if (i + 1 < selected.size()) {
                    crossovered.add(new ArrayList<>(parent2));
                }
            }
        }
        
        return crossovered;
    }
    
    /**
     * 修复课程安排中的冲突
     */
    private void repairSchedule(List<AcLessonSchedule> schedule) {
        Random random = new Random();
        Map<String, List<AcLessonSchedule>> conflicts = new HashMap<>();
        
        // 检测并收集冲突
        for (AcLessonSchedule lesson : schedule) {
            String timeSlot = lesson.getWeekDay() + "-" + lesson.getLessonNo();
            
            // 教师冲突
            String teacherKey = "T" + lesson.getTeacherId() + "-" + timeSlot;
            conflicts.computeIfAbsent(teacherKey, k -> new ArrayList<>()).add(lesson);
            
            // 教室冲突
            String classroomKey = "R" + lesson.getClassroomId() + "-" + timeSlot;
            conflicts.computeIfAbsent(classroomKey, k -> new ArrayList<>()).add(lesson);
            
            // 班级冲突
            String classKey = "C" + lesson.getClassId() + "-" + timeSlot;
            conflicts.computeIfAbsent(classKey, k -> new ArrayList<>()).add(lesson);
        }
        
        // 修复冲突
        for (List<AcLessonSchedule> conflictGroup : conflicts.values()) {
            if (conflictGroup.size() > 1) {
                // 保留第一个课程，重新安排其他冲突的课程
                for (int i = 1; i < conflictGroup.size(); i++) {
                    AcLessonSchedule lesson = conflictGroup.get(i);
                    
                    // 尝试找到新的时间段
                    boolean resolved = false;
                    for (int attempts = 0; attempts < 10 && !resolved; attempts++) {
                        int newWeekDay = random.nextInt(5) + 1;
                        int newLessonNo = random.nextInt(12) + 1;
                        
                        // 检查新时间段是否可用
                        if (isTimeSlotAvailable(schedule, lesson, newWeekDay, newLessonNo)) {
                            lesson.setWeekDay(newWeekDay);
                            lesson.setLessonNo(newLessonNo);
                            resolved = true;
                        }
                    }
                }
            }
        }
    }
    
    /**
     * 检查时间段是否可用
     */
    private boolean isTimeSlotAvailable(List<AcLessonSchedule> schedule, 
                                     AcLessonSchedule lesson,
                                     int weekDay, 
                                     int lessonNo) {
        for (AcLessonSchedule other : schedule) {
            if (other != lesson && other.getWeekDay() == weekDay && other.getLessonNo() == lessonNo) {
                // 检查教师冲突
                if (other.getTeacherId().equals(lesson.getTeacherId())) {
                    return false;
                }
                // 检查教室冲突
                if (other.getClassroomId().equals(lesson.getClassroomId())) {
                    return false;
                }
                // 检查班级冲突
                if (other.getClassId().equals(lesson.getClassId())) {
                    return false;
                }
            }
        }
        return true;
    }
    
    /**
     * 克隆课程安排对象
     */
    private AcLessonSchedule cloneSchedule(AcLessonSchedule schedule) {
        AcLessonSchedule clone = new AcLessonSchedule();
        clone.setId(schedule.getId());
        clone.setCourseId(schedule.getCourseId());
        clone.setTeacherId(schedule.getTeacherId());
        clone.setClassroomId(schedule.getClassroomId());
        clone.setClassId(schedule.getClassId());
        clone.setWeekDay(schedule.getWeekDay());
        clone.setLessonNo(schedule.getLessonNo());
        clone.setSemester(schedule.getSemester());
        clone.setTeacherPreference(schedule.getTeacherPreference());
        clone.setStatus(schedule.getStatus());
        return clone;
    }
    
    /**
     * 变异操作
     */
    private List<List<AcLessonSchedule>> mutation(List<List<AcLessonSchedule>> crossovered, Map<String, Object> constraints) {
        List<List<AcLessonSchedule>> mutated = new ArrayList<>();
        Random random = new Random();
        
        // 保留精英个体
        int eliteSize = (int) (crossovered.size() * ELITE_RATE);
        for (int i = 0; i < eliteSize; i++) {
            mutated.add(new ArrayList<>(crossovered.get(i)));
        }
        
        // 对剩余个体进行变异操作
        for (int i = eliteSize; i < crossovered.size(); i++) {
            List<AcLessonSchedule> chromosome = new ArrayList<>();
            
            for (AcLessonSchedule schedule : crossovered.get(i)) {
                AcLessonSchedule mutatedSchedule = cloneSchedule(schedule);
                
                // 按概率进行变异
                if (random.nextDouble() < MUTATION_RATE) {
                    // 随机选择变异类型
                    int mutationType = random.nextInt(3);
                    
                    switch (mutationType) {
                        case 0: // 变异时间
                            mutatedSchedule.setWeekDay(random.nextInt(5) + 1);
                            mutatedSchedule.setLessonNo(random.nextInt(12) + 1);
                            break;
                        case 1: // 变异教室
                            if (constraints.containsKey("classrooms")) {
                                @SuppressWarnings("unchecked")
                                List<Long> classrooms = (List<Long>) constraints.get("classrooms");
                                if (!classrooms.isEmpty()) {
                                    mutatedSchedule.setClassroomId(classrooms.get(random.nextInt(classrooms.size())));
                                }
                            }
                            break;
                        case 2: // 变异教师
                            if (constraints.containsKey("teachers")) {
                                @SuppressWarnings("unchecked")
                                List<Long> teachers = (List<Long>) constraints.get("teachers");
                                if (!teachers.isEmpty()) {
                                    mutatedSchedule.setTeacherId(teachers.get(random.nextInt(teachers.size())));
                                }
                            }
                            break;
                    }
                }
                
                chromosome.add(mutatedSchedule);
            }
            
            // 修复可能的冲突
            repairSchedule(chromosome);
            mutated.add(chromosome);
        }
        
        return mutated;
    }
    
    /**
     * 精英保留策略
     */
    private List<List<AcLessonSchedule>> elitism(List<List<AcLessonSchedule>> oldPopulation, 
                                              List<List<AcLessonSchedule>> newPopulation,
                                              Map<List<AcLessonSchedule>, Double> fitnessMap) {
        // 计算需要保留的精英数量
        int eliteCount = (int) (POPULATION_SIZE * ELITE_RATE);
        
        // 按适应度排序
        List<Map.Entry<List<AcLessonSchedule>, Double>> sortedFitness = new ArrayList<>(fitnessMap.entrySet());
        sortedFitness.sort(Map.Entry.<List<AcLessonSchedule>, Double>comparingByValue().reversed());
        
        // 创建新种群
        List<List<AcLessonSchedule>> result = new ArrayList<>();
        
        // 添加精英
        for (int i = 0; i < eliteCount && i < sortedFitness.size(); i++) {
            result.add(new ArrayList<>(sortedFitness.get(i).getKey()));
        }
        
        // 添加新一代个体
        for (int i = 0; i < POPULATION_SIZE - eliteCount && i < newPopulation.size(); i++) {
            result.add(newPopulation.get(i));
        }
        
        return result;
    }
    
    /**
     * 检查终止条件
     */
    private boolean checkTerminationCondition(Map<List<AcLessonSchedule>, Double> fitnessMap) {
        // 获取最高适应度
        double maxFitness = fitnessMap.values().stream().mapToDouble(Double::doubleValue).max().orElse(0);
        
        // 如果最高适应度达到阈值，则终止
        return maxFitness >= 950; // 假设950为较好的解决方案
    }
    
    // 当前迭代次数
    /** 当前迭代次数 */
    // private int generation = 0;

    
    /**
     * 获取最优解
     */
    private List<AcLessonSchedule> getBestSolution(List<List<AcLessonSchedule>> population) {

        // 计算每个染色体的适应度
        Map<List<AcLessonSchedule>, Double> fitnessMap = new HashMap<>();
        
        // 使用类成员变量constraints，避免创建新的空Map
        for (List<AcLessonSchedule> chromosome : population) {
            double fitness = calculateFitness(chromosome, this.constraints);
            fitnessMap.put(chromosome, fitness);
        }
        
        // 找出适应度最高的染色体
        return fitnessMap.entrySet().stream()
                .max(Map.Entry.comparingByValue())
                .map(Map.Entry::getKey)
                .orElse(new ArrayList<>());
    }
}